﻿using AutoMapper;
using B.S.BaseData.Domain.Entities.RBAC;
using B.S.BaseData.ErrorCode;
using B.S.BaseData.ErrorCode.ErrorCodes;
using B.S.BaseData.Infrastructure.Interfaces;
using B.S.DataBase.EFCoreServiers.Dtos.Depts;
using B.S.DataBase.EFCoreServiers.Dtos.Permissions;
using B.S.DataBase.EFCoreServiers.IServices.Permissions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace B.S.DataBase.EFCoreServiers.Services.Permissions
{
    public class PermissionServices : IPermissionServices
    {
        private readonly IPermissionRepository permission;

        private readonly IMapper mapper;
        private readonly IRolePermissionRepository rolePermission;

        public PermissionServices(IPermissionRepository permission, IMapper mapper, IRolePermissionRepository rolePermission)
        {
            this.permission = permission;
            this.mapper = mapper;
            this.rolePermission = rolePermission;
        }
        /// <summary>
        /// 添加权限
        /// </summary>
        /// <param name="permissionDto">权限数据传输对象</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> AddPermissiontAsync(AddPermissionDto permissionDto)
        {
            try
            {
                var existingRole = await permission.GetAll().FirstOrDefaultAsync(x => x.PermissionName == permissionDto.PermissionName);
                if (existingRole != null)
                {
                    return ApiResult.Fail("权限名称已存在", StatusCodeEnum.Fail);
                }

                var list = mapper.Map<Permission>(permissionDto);

                await permission.AddAsync(list);

                return ApiResult.Success(StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult.Fail("添加权限失败：" + ex.Message, StatusCodeEnum.Exception);
            }
        }

        /// <summary>
        /// 获取角色的权限树形结构
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <returns>权限树形结构</returns>
        public async Task<ApiResult<IList<PermissionTree>>> GetPermissiontAsync(int roleId)
        {
            try
            {
                // 1. 获取角色的所有权限ID 根据角色查询中间表 只拿权限id
                var rolePermissionIds = await rolePermission.GetAll()
                    .Where(x => x.RoleId == roleId)
                    .Select(x => x.PermissionId)
                    .ToListAsync();
                // 如果没有权限，直接返回空列表 any表示任何元素
                if (!rolePermissionIds.Any())
                {
                    return ApiResult<IList<PermissionTree>>.Success(new List<PermissionTree>(), StatusCodeEnum.Ok);
                }

                // 2. 一次性查询所有相关的权限信息
                var permissions = await permission.GetAll()
                    .Where(x => rolePermissionIds.Contains(x.PermissionId))
                    .ToListAsync();

                // 3. 按照Category分组构建树形结构
                var permissionTrees = permissions
                    .GroupBy(p => p.Category)
                    .Select(group => new PermissionTree
                    {
                        // 使用Category作为分组节点
                        Category = group.Key,
                        DisplayName = group.Key, // 分组名称显示为Category
                        Children = group.Select(p => new PermissionTree
                        {
                            PermissionId = p.PermissionId,
                            DisplayName = p.DisplayName,
                            Category = p.Category,
                        }).ToList()
                    })
                    .ToList();

                return ApiResult<IList<PermissionTree>>.Success(permissionTrees, StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult<IList<PermissionTree>>.Fail(
                    "获取角色权限失败：" + ex.Message, 
                    StatusCodeEnum.Exception
                );
            }
        }

        /// <summary>
        /// 获取菜单权限的树形
        /// </summary>
        /// <returns></returns>
        public async  Task<ApiResult<IList<GetMenuPermissionTree>>> GetMenuPermission(int ParentId = 0)
        {
            try
            {
                var menuPermissionTree = await permission.GetAll()
                    .Where(x => x.ParentId == ParentId) // 只获取顶级菜单权限
                    .Select(x => new GetMenuPermissionTree
                    {
                        PermissionId = x.PermissionId,
                        DisplayName = x.DisplayName,//权限名称
                        Category = x.Category,//所属模块
                        Pagepath = x.Pagepath,//页面路径
                        ParentId = x.ParentId,//父权限ID
                        Children = permission.GetAll()
                            .Where(child => child.ParentId == x.PermissionId) // 获取子权限=
                            .Select(child => new GetMenuPermissionTree
                            {
                                PermissionId = child.PermissionId,
                                DisplayName = child.DisplayName,
                                Category = child.Category,
                                Pagepath = child.Pagepath,
                                ParentId = child.ParentId
                            }).ToList()
                    }).ToListAsync();

                return ApiResult<IList<GetMenuPermissionTree>>.Success(menuPermissionTree, StatusCodeEnum.Ok);

            }
            catch (Exception ex)
            {
                return ApiResult<IList<GetMenuPermissionTree>>.Fail("获取菜单权限失败：" + ex.Message,
                    StatusCodeEnum.Exception
                );
            }
        }


        /// <summary>
        /// 获取所有权限
        /// </summary>
        /// <returns></returns>
        public async  Task<ApiResult<IList<GetAllPermissiontDto>>> GetAllPermissiontAsync()
        {
            try
            {
                var rermissionList = await permission.GetAll().ToListAsync();

                var permissionDtos = mapper.Map<IList<GetAllPermissiontDto>>(rermissionList);

                return ApiResult<IList<GetAllPermissiontDto>>.Success(permissionDtos, StatusCodeEnum.Ok);
            }
            catch (Exception ex)
            {
                return ApiResult<IList<GetAllPermissiontDto>>.Fail(
                    "获取权限失败：" + ex.Message,
                    StatusCodeEnum.Exception
                );
            }
        }

        /// <summary>
        /// 修改角色权限
        /// </summary>
        /// <param name="modifyRolePermissionsDto">包含角色ID和权限ID列表的数据传输对象</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> ModifyRolePermissionsAsync(ModifyRolePermissionsDto modifyRolePermissionsDto)
        {
            // 使用分布式事务
            using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, 
                new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }, 
                TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    // 1. 检查角色ID是否存在相关权限
                    var existingPermissions = await rolePermission.GetAll()
                        .Where(x => x.RoleId == modifyRolePermissionsDto.RoleId)
                        .ToListAsync();

                    // 2. 删除该角色的所有现有权限
                    foreach (var existingPerm in existingPermissions)
                    {
                        await rolePermission.DeleteAsync(existingPerm);
                    }
                    

                    // 3. 添加新的权限
                    if (modifyRolePermissionsDto.PermissionIds != null && modifyRolePermissionsDto.PermissionIds.Any())
                    {
                        var newRolePermissions = modifyRolePermissionsDto.PermissionIds.Select(permId => new RolePermission
                        {
                            RoleId = modifyRolePermissionsDto.RoleId,
                            PermissionId = permId
                        }).ToList();

                        await rolePermission.AddRangeAsync(newRolePermissions);
                    }

                    // 提交事务
                    transactionScope.Complete();
                    return ApiResult.Success( StatusCodeEnum.Ok);
                }
                catch (Exception ex)
                {
                    // 分布式事务会自动回滚，不需要显式调用 Rollback
                    return ApiResult.Fail("修改角色权限失败：" + ex.Message, StatusCodeEnum.Exception);
                }
            }




        }
    }
}
